﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormZhangYiDa
{
    public partial class FormZyd : Form
    {
        public FormZyd()
        {
            Log4NetHelper.InitLog4Net(Application.StartupPath + "\\log4net.config");
            InitializeComponent();
        }
   

        #region 定义成员变量
        /// <summary>
        /// 得分
        /// </summary>
        private int score = 0;
        /// <summary>
        /// 键盘状态，初始为 start
        /// </summary>
        string _Key_Name = "Start";
        /// <summary>
        /// 蛇身数组
        /// </summary>
        Label[] _Snake_Body = new Label[3000];
        /// <summary>
        /// 随机数生成Food
        /// </summary>
        Random _Random = new Random();
        /// <summary>
        /// 记录位置
        /// </summary>
        int Snake_Boby_content_x = 0, Snake_Boby_content_y = 0;
        #endregion
        public enum StartName {
            Start,
            Stop
        }
         
        private void FormZyd_Load(object sender, EventArgs e)
        {
           
            try
            {
               // Log4NetHelper.WriteError(new Exception().ToString());
               
                Bitmap _bitmap = new Bitmap(Resource.zyd);
                IntPtr h = _bitmap.GetHicon();
                this.Icon = System.Drawing.Icon.FromHandle(h);
                this.Text = "Snake张益达";
                this.Width = 1000;
                this.Height = 850;

                panel1.BorderStyle = BorderStyle.FixedSingle;
                panel1.Width = 800;
                panel1.Height = 840;
                Point _point = new Point
                {
                    X = this.Width - 150,
                    Y = 100
                };
                Point _point1 = new Point
                {
                    X = this.Width - 80,
                    Y = 100
                };
                label1.Location = _point;
                TxtScore.Location = _point1;
                //初始化蛇  5个label 一个label x =y=10
                for (int i = 0; i < 8; i++)
                {
                    //身段
                    Label Snake_Body_Content = new Label
                    {
                        Height = 10,
                        Width = 10,
                        Top = 200,//蛇的位置
                        Left = 200 - (i * 10),
                        BackColor = Color.Black,//背景色
                        ForeColor = Color.Black,
                        Text = "▉",  //显示类型
                        Tag = i
                    };

                    this.BackColor = Color.White;

                    //加入蛇体型
                    _Snake_Body[i] = Snake_Body_Content;
                    panel1.Controls.Add(Snake_Body_Content);
                }
                //每隔一段时间发生右移动
                timer1.Tick += new EventHandler(Timer_Tick);
                timer1.Interval = 1000;
                //检测事件监控
                Snake_food();
            }
            catch (Exception ex)
            {

                Log4NetHelper.WriteError(ex.ToString());
            }
        }

        public void Timer_Tick(object sender, EventArgs e) {

            int x, y;//记录Snake的Head的XY坐标
            x = _Snake_Body[0].Left;
            y = _Snake_Body[0].Top;
            switch (_Key_DownOldName)
            {
                case "Right":
                    if (_Key_Name == "Left") { _Key_Name = _Key_DownOldName; };
                    break;
                case "Start":
                    if (_Key_Name == "Left") { _Key_Name = _Key_DownOldName; };
                    break;
                case "Left":
                    if (_Key_Name == "Right") { _Key_Name = _Key_DownOldName; };
                    break;
                case "Up":
                    if (_Key_Name == "Down") { _Key_Name = _Key_DownOldName; };
                    break;
                case "Down":
                    if (_Key_Name == "Up") { _Key_Name = _Key_DownOldName; };
                    break;
            }
        
            if (_Key_Name == "Start" ) {
                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Left = x + 10; //向右偏移x+10

                SnakeMove(x, y);
            }
            if (_Key_Name == "Right" )
            {

                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Left = x + 10;
                SnakeMove(x, y);
            }
            if (_Key_Name == "Left")
            {
                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Left = x - 10;
                SnakeMove(x, y);
            }
            if (_Key_Name == "Up" )
            {
                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Top = y - 10;
                SnakeMove(x, y);
            }
            if (_Key_Name == "Down")
            {
                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Top = y + 10;
                SnakeMove(x, y);
            }
            SnakeOver();
            //穿墙设置
            if (x > 800) {

                _Snake_Body[0].Left = 0;
            }
            if (y > 840)
            {

                _Snake_Body[0].Top = 0;
            }
            if (x < 0)
            {

                _Snake_Body[0].Left = 800;
            }
            if (y < 0)
            {

                _Snake_Body[0].Top = 840;
            }

        }
        //移动
        public void SnakeMove(int x, int y) {
          
            //记录XY中间变量
            int Temp_X = 0, Temp_Y = 0;

            //蛇身移动
            for (int i = 1; _Snake_Body[i] != null; i++)
            {
                if (i >= 3) {
                    //将记录每个位置都给中间变量
                    Temp_X = Snake_Boby_content_x;
                    Temp_Y = Snake_Boby_content_y;
                }

                if (i == 1)
                {
                    Temp_X = _Snake_Body[i].Left; //将改变前的位置记录   X
                    Temp_Y = _Snake_Body[i].Top; //将改变前的位置记录 Y
                    _Snake_Body[i].Left = x; //并且赋值给第一蛇段
                    _Snake_Body[i].Top = y;

                }
                else {

                    Snake_Boby_content_x = _Snake_Body[i].Left;  //记录蛇段的改变前的位置
                    Snake_Boby_content_y = _Snake_Body[i].Top;

                    _Snake_Body[i].Left = Temp_X; //temp_赋给第二个蛇段,并记录改前位置
                    _Snake_Body[i].Top = Temp_Y;
                }
            }

        }
        public enum KeyAll {
            Start,
            UP,
            Down,
            Left,
            Right,

        }
        public void Snake_food() {

            Label Food = new Label
            {
                Width = 10,
                Height = 10,
                Top = _Random.Next(1, 20) * 20,
                Left = _Random.Next(1, 20) * 20,
                Text = "❤",
                Tag = "Food",
                BackColor = Color.White,
                ForeColor = Color.Black

            };
            panel1.Controls.Add(Food);
        }

        private void Btnstart_Click(object sender, EventArgs e)
        {
            this.KeyDown += new KeyEventHandler(FormZyd_KeyDown);
            timer1.Start();
            this.KeyPreview = true;
        }
        string _Key_DownOldName= "Start";
        /// <summary>
        /// 键盘相应事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormZyd_KeyDown(Object sender, KeyEventArgs e)
        {

            int x, y;
            x = _Snake_Body[0].Left;
            y = _Snake_Body[0].Top;
           
            _Key_Name = e.KeyCode.ToString();
            //获取键盘代码
            switch (_Key_DownOldName) {
                case "Right":
                    if (_Key_Name == "Left") { _Key_Name = _Key_DownOldName; } ;
                    break;
                case "Left":
                    if (_Key_Name == "Right") { _Key_Name = _Key_DownOldName; };
                    break;
                case "Up":
                    if (_Key_Name == "Down") { _Key_Name = _Key_DownOldName; };
                    break;
                case "Down":
                    if (_Key_Name == "Up") { _Key_Name = _Key_DownOldName; };
                    break;
            }
            if (_Key_Name == "Right") {

                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Left = x + 10;
                
                SnakeMove(x, y);
            }
            if (_Key_Name == "Left" )
            {
                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Left = x - 10;
               
                SnakeMove(x, y);
            }
            if (_Key_Name == "Up" )
            { 
                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Top = y - 10;
                
                SnakeMove(x, y);
            }
            if (_Key_Name == "Down")
            {
                _Key_DownOldName = _Key_Name;
                _Snake_Body[0].Top = y + 10;
                
                SnakeMove(x, y);
            }
            //每按一次，判断是否与食物重合
            Eat_time();
            SnakeOver();
        }
        /// <summary>
        /// 判断是否吃到实物
        /// </summary>
        public void Eat_time() {
            //取得食物的位置
            double x1 = 1, y1 = 1, x2 = 1, y2 = 1;
            foreach (Label _Label in this.panel1.Controls) {

                if (_Label.Tag.ToString() == "Food".ToString()) { //食物

                    x2 = _Label.Left;
                    y2 = _Label.Top;
                }
                if (_Label.Tag.ToString() == "0".ToString())//Snake 
                {
                    x1 = _Label.Left;
                    y1 = _Label.Top;
                }

                if (x1 == x2 && y1 == y2) {
                  // MessageBox.Show($"{x1},{y1},{x2},{y2}");
                    //吃掉食物 
                    Snake_Eat();
                    score++;
                    TxtScore.Text = $"共{score}分";
                    //将食物移位 更换坐标
                    foreach (Label lb in this.panel1.Controls)
                    {
                        if (lb.Tag.ToString() == "Food".ToString())
                        {
                            lb.Top = _Random.Next(1, 20) * 20;
                            lb.Left = _Random.Next(1, 20) * 20;
                        }
                    }

                }
            }
        }
        /// <summary>
        /// 吃掉食物
        /// </summary>
        public void Snake_Eat() {

            int i = 0;
            //遍历到蛇尾
            for (; _Snake_Body[i] != null; i++) ;
            //MessageBox.Show(i.ToString());
            Label Snake_Boby_content = new Label
            {
                Width = 10,
                Height = 10,
                Top = Snake_Boby_content_x,   //蛇尾位置X
                Left = Snake_Boby_content_y,  //蛇尾位置Y
                BackColor = Color.Black,
                Text = "▉",
                Tag = i,
            };
            _Snake_Body[i] = Snake_Boby_content;
            Snake_Boby_content.BackColor = Color.Black;
            this.Controls.Add(Snake_Boby_content);


        }
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Up || keyData == Keys.Down ||

                keyData == Keys.Left || keyData == Keys.Right)

                return false;
            else
                return base.ProcessDialogKey(keyData);

        }
        private void Btnsuspend_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            this.KeyPreview = false;
        }

        private void FormZyd_Paint(object sender, PaintEventArgs e)
        {
            //  Graphics g = CreateGdi();
        }
        /// <summary>
        /// 绘制曲线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            int col = 80;
            int row = 80;
            int drawRow = 0;
            int drawCol = 0;

            Pen pen = new Pen(Color.Gray, 1);
            Graphics g = this.panel1.CreateGraphics();
            for (int i = 0; i <= row; i++)
            {

                g.DrawLine(pen, 0, drawCol, 800, drawCol);
                drawCol += 10;
            }
            // 画垂直线
            for (int j = 0; j <= col; j++)
            {
                g.DrawLine(pen, drawRow, 0, drawRow, 800);
                drawRow += 10;
            }

        }

        /// <summary>
        /// 蛇头 碰见身体死亡
        /// </summary>
        public void SnakeOver() {

            int x, y;
            x = _Snake_Body[0].Left;
            y = _Snake_Body[0].Top;
            foreach (Label lb in this.panel1.Controls)
            {
                //将food排除
                if (lb.Tag.ToString() != "Food".ToString() && lb.Tag.ToString() != "score".ToString())
                {
                    //出现重合
                    if ((lb.Left == x && lb.Top == y) && lb.Tag.ToString() != "0")
                    {
                        timer1.Stop();
                        timer1.Enabled = false;
                        MessageBox.Show("GAME OVER !", "提示！");
                    }
                }
            }
        

        }
    }
}
